package com.tang.basics.introductory;

/**
 * 每一种数据都定义了明确的数据类型，在内存中分配不同的内存空间（字节）
 * java数据类型＝基本数据类型和引用数据类型
 * 基本数据类型
 * 数值型=整数类型，存放整数（byte[1],short[2],int[4],long[8]）
 * =浮点数类型，存放小数（float[4],double[8]）
 * 字符型=(char[2],存放单个字符　＂a＂)
 * 布尔型=(boolean[1],存放　true false)
 * 引用数据类型
 * 　　　类(class)
 * 接口(interface)
 * 数组([])
 */

/*重点　－　基本数据类型转换
 * 自动类型转换
 * 说明：当java 程序在进行赋值或者运算时，精度小的类型会自动转换为精度大的
 * 数据类型按精度大小排序（规则）
 * char >>> int >>> long >>> float >>> double
 * byte >>> short >>> int >>> long >>> float >>> double
 * 自动类型转换细节
 * １．有多种数据类型混合运算时，系统首先自动将所有数据转换成精度大的数据类型，然后在进行计算
 * ２．当我们把精度大的数据　赋值给精度小的数据类型时，就会报错，反之就会进行自动类型转换．
 * ３．byte short char 之间不会相互自动转换
 * ４．byte short char 他们３者可以计算，但是计算时首先转换为int类型
 * ５．boolean 不参与转换
 * ６．自动提升原则:表达式结果的类型自动提升为　操作数据类型中的最大类型．
 * */

public class NumericData_08 {

    public static void main(String[] args) {
        Boolean01 a = new Boolean01();
        a.dome1();
    }

}

//整数类型
class Integer01 {
    /*
     * 基本介绍
     * java 的整数类型就是用于存放整数的值，　10　20　30
     * 类型：byte[字节]　占用空间：1字节　范围：-128～127
     * 类型：short[短整数]　占用空间：2字节　范围：-(2^15)~2^15-1  -32768～32767
     * 类型：int[整型]　占用空间:4字节  范围：-(2^31)~2^31-1  -2147483648～2147483647
     * 类型：long[长整型]　占用空间:8字节　范围：-(2^63)~2^63-1
     * 注意细节
     * 1.java 的整型类型常量（具体值）默认为int ，声明long 型常量后需加　"l" 或　"L"
     * */

    //    案例演示 void 修饰不需要返回值　这个方法
    public void demo1() {
        byte n1 = 10;// 1个字节
        short n2 = 10;// 2个字节
        int n3 = 10; //4个字节
        long n4 = 10; //8个字节

    }

    /*
     * 1.java 的整型类型常量（具体值）默认为int ，声明long 型常量后需加　"l" 或　"L"
     * */
    public void demo2() {
//        长整型使用:java 的整型类型常量（具体值）默认为int ，声明long 型常量后需加　"l" 或　"L"
        int n1 = 1;
//        int n2=1L;//错误
        long n3 = 4L;//对
    }

}


//浮点类型
class Floating {
    /*
     * 基本介绍
     * １．Java 的浮点类型可以表示一个小数，比如 123.4 ，7.8 ，0.12 等等
     * 类型：float－单精度　　占用空间：4字节　范围：-3.403Ｅ38～3.403Ｅ38
     * 类型：double－双精度　　占用空间：4字节　范围：-1.798E308～1.798E308
     * 说明一下
     * 1) 关于浮点数在机器中存放形式的简单说明,浮点数=符号位+指数位+尾数位
     * 2) 尾数部分可能丢失，造成精度损失(小数都是近似值)。
     *
     * double num9 =2.1234567851;
     * float num10 = 2.1234567851F;
     * 5.浮点数使用陷阱: 2.7和8.1 / 3比较
     * double num7 = 2.7;
     * double num8=8.1/ 3;
     * if( Math.abs(num7 - num8) < 0.00001) {
     *   System.out. println("相等~");
     * }
     *
     *
     * */
    public static void details() {
        //Java 的浮点型常量(具体值)默认为 double 型，声明 float 型常量，须后加‘f’或‘F'
        //float num1 = 1.1; //错误
        float num2 = 1.1F; //对的
        double num3 = 1.1; //对
        double num4 = 1.1f; //对

        //十进制数形式：如：5.12 512.0f .512 (必须有小数点）
        double num5 = .123; //等价 0.123
        System.out.println(num5);

        //科学计数法形式:如：5.12e2 [5.12 * 10 的 2 次方 ] 5.12E-2 []
        System.out.println(5.12e2);//512.0
        System.out.println(5.12E-2);//0.0512

        //通常情况下，应该使用 double 型，因为它比 float 型更精确。
        //[举例说明]double num9 = 2.1234567851;float num10 = 2.1234567851F;
        double num9 = 2.1234567851;
        float num10 = 2.1234567851F;
        System.out.println(num9); //2.1234567851
        System.out.println(num10); //2.1234567

        //浮点数使用陷阱: 2.7 和 8.1 / 3 比较
        //看看一段代码
        double num11 = 2.7;  //2.7
        //double num12 = 2.7; //2.7
        double num12 = 8.1 / 3; //接近 2.7 的一个小数，而不是 2.7
        System.out.println(num11);//2.7
        System.out.println(num12);//2.6999999999999997

        // 得到一个重要的使用点: 当我们对运算结果是小数的进行相等判断是，要小心
        if (num11 == num12) {
            System.out.println("num11 == num12 相等");
        }
        // 应该是以两个数的差值的绝对值，在某个精度范围类判断
        if (Math.abs(num11 - num12) < 0.000001) {
            System.out.println("差值非常小，到我的规定精度，认为相等...");
        }
        // 可以通过 java API 来看
        System.out.println(Math.abs(num11 - num12));
        //细节:如果是直接查询得的的小数或者直接赋值，是可以判断相等
        //4.440892098500626E-16

    }
}


class Char {

    public void dome1() {
        char c1 = 'a';
        char c2 = '\t'; // 特殊字符型常量
        char c3 = '韩';
        char c4 = 97;

    }

    // 字符串细节
    public void details() {
        //在 java 中，char 的本质是一个整数，在默认输出时，是 unicode 码对应的字符
        //要输出对应的数字，可以(int)字符
        char c1 = 97;
        System.out.println(c1); // a
        char c2 = 'a'; //输出'a' 对应的 数字
        System.out.println((int) c2);
        char c3 = '韩';
        System.out.println((int) c3);//38889
        char c4 = 38889;
        System.out.println(c4);//韩
        //char 类型是可以进行运算的，相当于一个整数，因为它都对应有 Unicode 码.
        System.out.println('a' + 10);//107
    }

    public void test() {
        char c5 = 'b' + 1;//98+1=99
        System.out.println((int) c5); //99
        System.out.println(c5); //99->对应的字符->编码表 ASCII(规定好的)=>c
    }

}


//布尔类型
class Boolean01 {
    public void dome1() {
        //演示判断成绩是否通过的案例
        //定义一个布尔变量
        boolean isPass = false;
        if (isPass == true) {
            System.out.println("考试通过，恭喜");
        } else {
            System.out.println("考试没有通过，下次努力");
        }
    }
}


//自动类型转换细节
class AutoConvertDetail {
    public void dome1() {
        //细节 1： 有多种类型的数据混合运算时，
        //系统首先自动将所有数据转换成容量最大的那种数据类型，然后再进行计算
        int n1 = 10; //ok
        //float d1 = n1 + 1.1;//错误 n1 + 1.1 => 结果类型是 double
        //double d1 = n1 + 1.1;//对 n1 + 1.1 => 结果类型是 double
        float d1 = n1 + 1.1F;//对 n1 + 1.1 => 结果类型是 float
        //细节 2: 当我们把精度(容量)大 的数据类型赋值给精度(容量)小 的数据类型时，就会报错，反之就会进行自动类型转换。
        //int n2 = 1.1;//错误 double -> int
        //细节 3: (byte, short) 和 char 之间不会相互自动转换
        //当把具体数赋给 byte 时，(1)先判断该数是否在 byte 范围内，如果是就可以
        byte b1 = 10; //对 , -128-127
        // int n2 = 1; //n2 是 int
        // byte b2 = n2; //错误，原因： 如果是变量赋值，判断类型
        //char c1 = b1; //错误， 原因 byte 不能自动转成 char
        //细节 4: byte，short，char 他们三者可以计算，在计算时首先转换为 int 类型
        byte b2 = 1;
        byte b3 = 2;
        short s1 = 1;
        //short s2=b2+s1;//错,b2+s1=>int
        int s2 = b2 + s1;//对,b2+s1=>int
        //byteb4=b2+b3;//错误:b2+b3=>int
        //boolean不参与转换
        // booleanpass=true;
        //intnum100=pass;//boolean不参与类型的自动转换
        //自动提升原则： 表达式结果的类型自动提升为 操作数中最大的类型
        byte b4 = 1;
        short s3 = 100;
        int num200 = 1;
        float num300 = 1.1F;
        double num500 = b4 + s3 + num200 + num300; //float -> double
    }
}


/*
 * 强制类型转换
 * 自动类型转换的逆过程，将容量大的数据类型转换为容量小的数据类型。使用时要加上强制转换符 ( )，但可能造成 精度降低或溢出,格外要注意。
 * 强制类型转换细节说明
 * 1.当进行数据大小从　大＞＞＞小　，就需要使用强制转换
 * 2.强制转换符号只针对于最近的操作数有效，往往会使用小括号提升优先级．
 * 3. char 类型可以保存int的常量值．但不能保存int的变量值　需要强转
 * 4. byte short char 进行运算时　，当作int处理
 *
 * */


class ForceConvertDetail {
    public static void dome() {
        //演示强制类型转换
        //强转符号只针对于最近的操作数有效，往往会使用小括号提升优先级
        //int x = (int)10*3.5+6*1.5;//编译错误： double -> int
        int x = (int) (10 * 3.5 + 6 * 1.5);// (int)44.0 -> 44
        System.out.println(x);//44
        char c1 = 100; //ok
        int m = 100; //ok
        //char c2 = m; //错误  Int >>> char
        char c3 = (char) m; //ok
        System.out.println(c3);//100 对应的字符, d 字符
    }


    public static void dome2() {
        short s = 12; //ok
        //s = 9-s; // 错误　int >>>short
        byte b=10; //ok
        //b=b+11; //错误　int >>> byte

        char a ='a';// ok
        int i = 16;// ok
        float d=.314F;//ok
        double rest=a+i+d;//ok

        byte c= 16;//ok
        short x=14;//ok
        //short o=x+c; // 错误　ｉint >>> short

    }
}


/*
* 基本数据类型和 String 类型的转换
* 在程序开发中，我们经常需要将基本数据类型转成String类型。或者将String类型转成基本数据类型。
* 在将 String 类型转成 基本数据类型时， ，比如 我们可以把 "123" , 转成一 个整数，但是不能把 "hello" 转成一个整数
* 如果格式不正确，就会抛出异常，程序就会终止， 这个问题在异常处理章节中，会处理
* */

class StringToBasic {
    public static void dome1() {
        //基本数据类型->String
        int n1 = 100;
        float f1 = 1.1F;
        double d1 = 4.5;
        boolean b1 = true;
        String s1 = n1 + "";
        String s2 = f1 + "";
        String s3 = d1 + "";
        String s4 = b1 + "";
        System.out.println(s1 + " " + s2 + " " + s3 + " " + s4);
        //String->对应的基本数据类型
        String s5 = "123";
        //会在 OOP 讲对象和方法的时候回详细
        //解读 使用 基本数据类型对应的包装类，的相应方法，得到基本数据类型
        int num1 = Integer.parseInt(s5);
        double num2 = Double.parseDouble(s5);
        float num3 = Float.parseFloat(s5);
        long num4 = Long.parseLong(s5);
        byte num5 = Byte.parseByte(s5);
        boolean b = Boolean.parseBoolean("true");
        short num6 = Short.parseShort(s5);
        System.out.println("===================");
        System.out.println(num1);//123
        System.out.println(num2);//123.0
        System.out.println(num3);//123.0
        System.out.println(num4);//123
        System.out.println(num5);//123
        System.out.println(num6);//123
        System.out.println(b);//true

        //怎么把字符串转成字符 char -> 含义是指 把字符串的第一个字符得到
        //解读 s5.charAt(0) 得到 s5 字符串的第一个字符 '1
        System.out.println(s5.charAt(0));
    }

    //* 演示字符串转基本数据类型的细节
    public static void dome2() {
        String str = "hello"; //转成 int
        int n1 = Integer.parseInt(str); //运行报错 ,在转换时必须符合基本数据类型要求，是能够转换的！a 不能　int  1就可以
        System.out.println(n1);
    }
}


